import winston from 'winston';
import DailyRotateFile from 'winston-daily-rotate-file';
import path from 'path';
import fs from 'fs';

// 日志级别定义
export enum LogLevel {
  ERROR = 'error',
  WARN = 'warn',
  INFO = 'info',
  HTTP = 'http',
  DEBUG = 'debug'
}

// 日志配置接口
interface LoggerConfig {
  level: LogLevel;
  logDir: string;
  maxFiles: string;
  maxSize: string;
  datePattern: string;
  enableConsole: boolean;
  enableFile: boolean;
}

// 默认配置
const defaultConfig: LoggerConfig = {
  level: process.env.NODE_ENV === 'production' ? LogLevel.INFO : LogLevel.DEBUG,
  logDir: process.env.LOG_DIR || path.join(process.cwd(), 'logs'),
  maxFiles: '14d', // 保留14天的日志
  maxSize: '20m',  // 单个文件最大20MB
  datePattern: 'YYYY-MM-DD',
  enableConsole: process.env.NODE_ENV !== 'production',
  enableFile: true
};

// 自定义日志格式
const logFormat = winston.format.combine(
  winston.format.timestamp({
    format: 'YYYY-MM-DD HH:mm:ss.SSS'
  }),
  winston.format.errors({ stack: true }),
  winston.format.json(),
  winston.format.printf(({ timestamp, level, message, stack, ...meta }) => {
    let logMessage = `${timestamp} [${level.toUpperCase()}]: ${message}`;
    
    // 添加堆栈信息（如果存在）
    if (stack) {
      logMessage += `\n${stack}`;
    }
    
    // 添加额外的元数据
    if (Object.keys(meta).length > 0) {
      logMessage += `\n${JSON.stringify(meta, null, 2)}`;
    }
    
    return logMessage;
  })
);

// 控制台格式（更简洁）
const consoleFormat = winston.format.combine(
  winston.format.colorize(),
  winston.format.timestamp({
    format: 'HH:mm:ss'
  }),
  winston.format.printf(({ timestamp, level, message }) => {
    return `${timestamp} ${level}: ${message}`;
  })
);

class Logger {
  private logger: winston.Logger;
  private config: LoggerConfig;

  constructor(config: Partial<LoggerConfig> = {}) {
    this.config = { ...defaultConfig, ...config };
    this.ensureLogDirectory();
    this.logger = this.createLogger();
  }

  private ensureLogDirectory(): void {
    if (this.config.enableFile && !fs.existsSync(this.config.logDir)) {
      fs.mkdirSync(this.config.logDir, { recursive: true });
    }
  }

  private createLogger(): winston.Logger {
    const transports: winston.transport[] = [];

    // 控制台输出
    if (this.config.enableConsole) {
      transports.push(
        new winston.transports.Console({
          level: this.config.level,
          format: consoleFormat
        })
      );
    }

    // 文件输出
    if (this.config.enableFile) {
      // 应用日志文件
      transports.push(
        new DailyRotateFile({
          filename: path.join(this.config.logDir, 'application-%DATE%.log'),
          datePattern: this.config.datePattern,
          maxFiles: this.config.maxFiles,
          maxSize: this.config.maxSize,
          level: this.config.level,
          format: logFormat
        })
      );

      // 错误日志文件（只记录错误）
      transports.push(
        new DailyRotateFile({
          filename: path.join(this.config.logDir, 'error-%DATE%.log'),
          datePattern: this.config.datePattern,
          maxFiles: this.config.maxFiles,
          maxSize: this.config.maxSize,
          level: LogLevel.ERROR,
          format: logFormat
        })
      );

      // SQL执行日志文件
      transports.push(
        new DailyRotateFile({
          filename: path.join(this.config.logDir, 'executions', 'sql-execution-%DATE%.log'),
          datePattern: this.config.datePattern,
          maxFiles: this.config.maxFiles,
          maxSize: this.config.maxSize,
          level: LogLevel.INFO,
          format: logFormat
        })
      );
    }

    return winston.createLogger({
      level: this.config.level,
      transports,
      exitOnError: false
    });
  }

  // 基础日志方法
  error(message: string, meta?: any): void {
    this.logger.error(message, meta);
  }

  warn(message: string, meta?: any): void {
    this.logger.warn(message, meta);
  }

  info(message: string, meta?: any): void {
    this.logger.info(message, meta);
  }

  http(message: string, meta?: any): void {
    this.logger.http(message, meta);
  }

  debug(message: string, meta?: any): void {
    this.logger.debug(message, meta);
  }

  // 专用日志方法
  sqlExecution(executionId: string, sql: string, duration: number, status: 'success' | 'error', error?: string): void {
    const logData = {
      executionId,
      sql: sql.substring(0, 500), // 截取前500字符避免日志过长
      duration,
      status,
      error,
      timestamp: new Date().toISOString()
    };

    if (status === 'error') {
      this.error(`SQL execution failed: ${executionId}`, logData);
    } else {
      this.info(`SQL execution completed: ${executionId}`, logData);
    }
  }

  apiRequest(method: string, url: string, statusCode: number, duration: number, userId?: string): void {
    const logData = {
      method,
      url,
      statusCode,
      duration,
      userId,
      timestamp: new Date().toISOString()
    };

    this.http(`${method} ${url} ${statusCode} - ${duration}ms`, logData);
  }

  userAction(userId: string, action: string, resource: string, resourceId?: string, details?: any): void {
    const logData = {
      userId,
      action,
      resource,
      resourceId,
      details,
      timestamp: new Date().toISOString()
    };

    this.info(`User action: ${userId} ${action} ${resource}`, logData);
  }

  systemEvent(event: string, details?: any): void {
    const logData = {
      event,
      details,
      timestamp: new Date().toISOString()
    };

    this.info(`System event: ${event}`, logData);
  }

  // 性能监控
  performance(operation: string, duration: number, details?: any): void {
    const logData = {
      operation,
      duration,
      details,
      timestamp: new Date().toISOString()
    };

    if (duration > 5000) { // 超过5秒的操作记录为警告
      this.warn(`Slow operation detected: ${operation} took ${duration}ms`, logData);
    } else {
      this.debug(`Performance: ${operation} took ${duration}ms`, logData);
    }
  }

  // 清理旧日志文件
  async cleanupLogs(daysToKeep: number = 30): Promise<void> {
    try {
      const cutoffDate = new Date();
      cutoffDate.setDate(cutoffDate.getDate() - daysToKeep);

      const files = fs.readdirSync(this.config.logDir);
      
      for (const file of files) {
        const filePath = path.join(this.config.logDir, file);
        const stats = fs.statSync(filePath);
        
        if (stats.isFile() && stats.mtime < cutoffDate) {
          fs.unlinkSync(filePath);
          this.info(`Cleaned up old log file: ${file}`);
        }
      }
    } catch (error) {
      this.error('Failed to cleanup logs', { error: error instanceof Error ? error.message : String(error) });
    }
  }

  // 获取日志统计信息
  getLogStats(): { totalFiles: number; totalSize: number; oldestFile: Date | null } {
    try {
      const files = fs.readdirSync(this.config.logDir);
      let totalSize = 0;
      let oldestFile: Date | null = null;

      for (const file of files) {
        const filePath = path.join(this.config.logDir, file);
        const stats = fs.statSync(filePath);
        
        if (stats.isFile()) {
          totalSize += stats.size;
          
          if (!oldestFile || stats.mtime < oldestFile) {
            oldestFile = stats.mtime;
          }
        }
      }

      return {
        totalFiles: files.length,
        totalSize,
        oldestFile
      };
    } catch (error) {
      this.error('Failed to get log stats', { error: error instanceof Error ? error.message : String(error) });
      return { totalFiles: 0, totalSize: 0, oldestFile: null };
    }
  }
}

// 创建默认logger实例
const logger = new Logger();

// 导出logger实例和类
export { Logger };
export default logger;